home *** CD-ROM | disk | FTP | other *** search
/ Workbench Design / WB Collection.iso / workbench werkzeuge / kickstart tools / softboot3.31 / softag.asm < prev    next >
Assembly Source File  |  1996-04-07  |  41KB  |  1,298 lines

  1. *
  2. *  SofTag V3.31 -- By Greg Tibbs 10/25/1992
  3. *
  4. *             Inspired by ZKick 3.01 by Daniel Zenchelsky
  5. *             Assemble with SAS/C 6.00 ASM
  6. *
  7.  
  8.    NOLIST
  9.    INCLUDE "exec/types.i"
  10.    INCLUDE "exec/tasks.i"
  11.    INCLUDE "exec/resident.i"
  12.    INCLUDE "exec/execbase.i"
  13.    INCLUDE "SoftBoot.i"
  14.    LIST
  15.  
  16.    SECTION   code
  17.  
  18.    XDEF   _TC030
  19.    XDEF   _Z3cache
  20.    XDEF   _CRP0
  21.    XDEF   _CRP1
  22.    XDEF   _BusErr
  23.    XDEF   _CatchRom
  24.    XDEF   _SRP
  25.    XDEF   @MakeRomTag
  26.    XDEF   @CachesOff
  27.    XDEF   @SF_Supervisor
  28.    XDEF   _LogRomStart
  29.    XDEF   _PhyRomStart
  30.    XDEF   @JTRom
  31.    XDEF   @MyColdReboot
  32.    XDEF   @SpeedRom
  33.    XDEF   @GetCPUType
  34.    XDEF   @GetTC040
  35.    XDEF   @GetTC030
  36.    XDEF   @KillRomTags
  37.    XDEF   _NumMemAreas
  38.    XDEF   _MemListArray
  39.    XDEF   @JTRom13030
  40.    XDEF   @MakeRomTag13
  41.    XDEF   _IDCpu
  42.    XDEF   @ForceTTX
  43.    XREF   _LVOSupervisor
  44.    XREF   _LVODisable
  45.    XREF   _LVOSuperState
  46.    XREF   _LVOAllocAbs
  47.    XREF   _LVOEnable
  48.    XREF   _LVOSumKickData
  49.    XREF   _LVOSetFunction
  50.  
  51. VERSION:        EQU     3
  52. REVISION:       EQU     31
  53. MYPRI           EQU     127
  54. _LVOColdReboot  EQU     -726
  55. ABSEXECBASE     EQU     (4)
  56.  
  57.                 CNOP    0,4
  58.  
  59. ;-----------------------------------------------------------------------
  60. ; From here on is protected from erasure during reboot
  61. ;-----------------------------------------------------------------------
  62. ; 128 byte Buffer Area in case of AllocMem Memlist tail overwrite!
  63.  
  64. _SaveMem:
  65.  
  66.             DC.L  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  67.                 DC.L  0,0,0,0,0,0,0,0
  68.  
  69. KickMem:                ;Area for KickMemList data
  70.                DC.L   0,0,0,0
  71. _MemListArray   DC.L   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  72.                 DC.L   0,0,0,0,0,0,0,0,0
  73. KickTag:
  74.             DC.L    initDDescrip
  75.             DC.L    0       ;Next Romtag initDescrip Pointer
  76.  
  77. _CRP0:          DC.L    $7fff0002
  78. _CRP1:          DC.L    0
  79. _TC030:         DC.L    $80f0d400
  80. _SRP:           DC.L    0
  81. _PhyRomStart:   DC.L    0
  82. _LogRomStart:   DC.L    $00f80000
  83. _BusErr:        DC.L    0
  84. _CatchRom:      DC.L    0
  85. _Z3cache        DC.L    1
  86. _NumMemAreas:   DC.L    3
  87. ROMColdReboot:  DC.L    0
  88. Zero:           DC.L    0
  89.             DC.L    0
  90.  
  91. ;-----------------------------------------------------------------------
  92. ; A romtag structure.  Both "exec" and "ramlib" look for
  93. ; this structure to discover magic constants about you
  94. ; (such as where to start running you from...).
  95. ;-----------------------------------------------------------------------
  96.  
  97.    ; Most people will not need a priority and should leave it at zero.
  98.    ; the RT_PRI field is used for _configuring the roms.  Use "mods" from
  99.    ; wack to look at the other romtags in the system
  100.  
  101. initDDescrip:
  102.                             ; STRUCTURE RT,0
  103.      DC.W    RTC_MATCHWORD      ; UWORD RT_MATCHWORD
  104.      DC.L    initDDescrip       ; APTR  RT_MATCHTAG
  105.      DC.L    _EndTag            ; APTR  RT_ENDSKIP
  106.      DC.B    RTF_COLDSTART      ; UBYTE RT_FLAGS
  107.      DC.B    VERSION            ; UBYTE RT_VERSION
  108.      DC.B    NT_UNKNOWN         ; UBYTE RT_TYPE
  109.      DC.B    MYPRI              ; BYTE  RT_PRI
  110.      DC.L    modName            ; APTR  RT_NAME
  111.      DC.L    idString           ; APTR  RT_IDSTRING
  112.      DC.L    _InitRoutine       ; APTR  RT_INIT
  113.  
  114.  
  115.    ; this is the name that the module will have
  116.  
  117. modName:        DC.B   'SoftBoot.romtag  ',0
  118.  
  119. idString:       DC.B   'SoftBoot.romtag 3.31 (10/25/92)',13,10,0
  120.  
  121.     CNOP 0,4
  122.  
  123. _InitRoutine:           
  124.  
  125.     movem.l d0-d7/a0-a6,-(a7)   ;Save Registers
  126.     move.l  ABSEXECBASE,a6      ;Get Execbase
  127.  
  128. ;
  129. ;   The following code protects the ROM by allocating its RAM image
  130. ;   at 7f80000. Normally this would be done in the KickMemList,
  131. ;   but 2.0 has a wonderful feature that if it detects a 68030CPU
  132. ;   with its MMU on at boot time, it will autoallocate that area,
  133. ;   causing the kickmemlist allocation to fail. By using the ROM at
  134. ;   the same address and not caring whether or not the AllocABs
  135. ;   passes or fails, similar memory models can be had for the
  136. ;   68040 CPU as well as the 030. This is all done for the nice 
  137. ;   feature of making RAD work when switching CPUs. This risks
  138. ;   another romtag allocating something in this area, so the 
  139. ;   priority has been increased to the maximum of 127. If some
  140. ;   future OS takes away the autoallocate SuperKickstart 'feature',
  141. ;   the current code will continue to work. It also pushes the
  142. ;   Largest memory fragment to the end of A3000 motherboard RAM,
  143. ;   reducing memory clutter.
  144. ;
  145. ;   The following code also allocates the 16 bytes in front of the
  146. ;   ROM to prevent a MemList tail from overwriting it. That allocation
  147. ;   will also overwrite the first two long words, so they are copied to
  148. ;   the stack and restored after the allocation.
  149. ;
  150.     move.l  #$7f80000,a0        ;Ram Address of Start of Rom
  151.     move.l  (a0)+,a2            ;Get 1st Long Word
  152.     move.l  (a0)+,a3            ;Get 2nd Long word
  153.     movem.l a2-a3,-(a7)         ;Save on stack
  154.  
  155.     moveq   #$10,d0             ;Number of bytes ahead of ROM to protect
  156.     move.l  #$7f7fff0,a1        ;Address to allocate
  157.     jsr     _LVOAllocAbs(a6)
  158.  
  159.     move.l  #$80000,d0          ;# of bytes to allocate in ROM
  160.     move.l  #$7f80000,a1        ;Rom Address
  161.     jsr     _LVOAllocAbs(a6)       ;If fails, 2.0 must have already allocated
  162.                             ; this area for me - how nice! thumppp!
  163.     movem.l (a7)+,a2-a3         ;Fix MemList tail overwrite of 1st two Rom
  164.     move.l  #$7f80000,a0        ;   long words
  165.     move.l  a2,(a0)+            ;Restore 2nd Longword of ROM
  166.     move.l  a3,(a0)+            ;Restore 1st Longword of ROM
  167. ;
  168. ; Now take over ColdReboot() so My MMU tables will be loaded at a software reset
  169. ;
  170.     jsr SFColdReboot
  171. ;
  172. ;   Now Check CPU and handle if a reboot or a pass thru, if a particular
  173. ;   CPU does not have MMU tables setup, then it will pass thru, although
  174. ;   MMU tables for the other CPU will continue to be protected if they
  175. ;   were ever generated in the first place.
  176. ;
  177.     btst.b  #AFB_68040,ATNFLGS(a6)
  178.     beq.b   Do030               ;Jump to next test if not 040
  179.  
  180.     move.l  _SRP,d0             ;Test if 040 MMU tables are setup
  181.     cmpi.l  #0,d0               ;No MMU tables if SRP = 0
  182.     beq.b   ExitInit
  183.     
  184.     lea.l    My040InitCode,a5   ;Load code pointer 
  185.     jsr     _LVOSupervisor(a6)  ;Run code in Supervisor Mode
  186.     bra.b    ExitInit           ;Return to OS
  187.  
  188. Do030:
  189.     btst.b  #AFB_68030,ATNFLGS(a6)  ;Test for 030
  190.     bne.b   Ok030   
  191.  
  192.     btst.b  #AFB_68020,ATNFLGS(a6)  ;Test for 020 (851 assumed)
  193.     beq.b   ExitInit                ;Just return if not a 020 or better
  194.  
  195. Ok030:
  196.     move.l  _CRP1,d0            ;Test if 030/020&851 MMU tables are setup
  197.     cmpi.l  #$0,d0              ;No MMU tables if CRP = 0
  198.     beq.b   ExitInit
  199.     
  200.     lea.l    My030InitCode,a5   ;Load code pointer 
  201.     jsr     _LVOSupervisor(a6)  ;Run code in Supervisor Mode
  202.  
  203. ExitInit:
  204.  
  205.     movem.l (a7)+,d0-d7/a0-a6   ;Restore Registers
  206.     rts                     ;Return to OS
  207.  
  208. My030InitCode: 
  209.  
  210.     bsr     SetMMU030   ;This Must be called for the hardware reset conditon
  211.     btst.l  #31,d1
  212.     beq     Reboot      ;MMU off, turn on to initial state and reboot
  213.     rte
  214.  
  215. ;Load Exception handler and take care of Software and Hardware reset conditions
  216.  
  217. SetBusErrorHandler:
  218.     
  219.     move.l  _BusErr,d0          ;Check if we want to disable Bus Errors
  220.     cmpi.l  #0,d0           
  221.     beq.b   DoneBus             ;Branch if non zero
  222.     move.b  #0,($DE0000)        ;Set Buster to no Bus Error time out
  223.  
  224. DoneBus:
  225.  
  226.     move.l  _CatchRom,d0        ;load and test Error Handler Bypass
  227.     cmpi.l  #0,d0           
  228.     bne.b   SBEHend
  229.     _MOVEC  vbr,d0              ;Get VBR. Should be zero, but never know
  230.     move.l  d0,a0       
  231.     move.l  $8(a0),a1           ;Get Old Bus Error Handler Address
  232.     move.l  a1,OH1              ;Store it
  233.     lea.l   _BusErrorHandler,a1 ;Get new handler address
  234.     move.l  a1,$8(a0)           ;Write to exception table
  235.     move.l  a1,8                ;Write to address 8 for good measure 
  236.  
  237. SBEHend:    
  238.     rts
  239.  
  240. My040InitCode:
  241.  
  242.     bsr     SetBusErrorHandler
  243.     bsr     SetMMU      ;This Must be called for the hardware reset conditon
  244.     cmpi.l  #0,d1
  245.     beq     Reboot      ;MMU off, turn on to initial state and reboot
  246.  
  247.                     ;Change Cache code for Fast Ram 
  248.  
  249.     _CPUSHA040          ;Dump Caches to RAM
  250.     _PFLUSHA040         ;Clear ATC
  251.     _CINVA040           ;Invalidate caches - Note SetMMU cleared cacr
  252.  
  253.     move.l  _Z3cache,d1     ; if d1 is non-zero, turn on dttx copyback mode
  254.     cmpi.l  #0,d1
  255.     beq     BypassMMU          ; Zero, therefore leave dttx as is  
  256.  
  257.     move.l  #$08f7c020,d0       ;Turn on Copyback mode for data acesses
  258.     _MOVEC  d0,dtt1
  259.     move.l  #$04fbc020,d0
  260.     _MOVEC  d0,dtt0
  261.  
  262.     _PFLUSHA040             ;Kill ATC and Caches again for extra good measure
  263.     _CINVA040
  264.  
  265. BypassMMU:
  266.     rte
  267.  
  268. Reboot: 
  269.     nop
  270.     move.l  _LogRomStart,a0
  271.     adda.l  #2,a0
  272.     bra     LongAddr1
  273.     CNOP    0,4
  274.  
  275. LongAddr1:
  276.  
  277.     reset
  278.     jmp (a0)
  279.     
  280. SetMMU: 
  281.  
  282.     _MOVEC  tc,d1           ;Move Get Translation Control Register
  283.  
  284.     cmpi.w  #$0,d1          ;Test if MMU is already on
  285.     bne     mmu_on          ;if so, bypass and return with TC contents 
  286.                         ;  as status
  287. SetMMU1:
  288.  
  289.     moveq   #0,d1           ;Clear out VBR, TC, and CACR
  290.     _MOVEC  d1,vbr
  291.  
  292. SetMMU2:
  293.  
  294.     _MOVEC  d1,tc
  295.     _MOVEC  d1,cacr
  296.  
  297.     _CPUSHA040              ;Dump Caches
  298.     _PFLUSHA040             ;Clear out ATC
  299.     _CINVA040               ;Invalidate caches
  300.  
  301.     move.l  _SRP,d1         ;Write MMU Root table pointer to SRP & URP
  302.     _MOVEC  d1,srp
  303.     _MOVEC  d1,urp
  304.  
  305.     move.l  #$04fbc040,d1       ;Set up MMU for default memory translation setup
  306.     _MOVEC  d1,dtt0
  307.     move.l  #$08f7c040,d1
  308.     _MOVEC  d1,dtt1
  309.  
  310.     move.l  #$04fbc000,d1
  311.     _MOVEC  d1,itt0
  312.     move.l  #$08f7c000,d1
  313.     _MOVEC  d1,itt1
  314.  
  315.     _CPUSHA040              ;Dump and Kill caches once again
  316.     _PFLUSHA040
  317.     _CINVA040
  318.    
  319.     move.w  #$C000,d0       ;Load TC (8K tables)
  320.     _MOVEC  d0,tc               ; Activate TC
  321.     move.l  #0,d1           ;Return code for testing if MMU was on at
  322.                         ;Start of SetMMU - 0 indicates it was off
  323. mmu_on:
  324.     rts
  325.     
  326. SetMMU030:      
  327.  
  328.     lea.l   StackCopy,a0        ;Clear tc
  329.  
  330.     _PMOVE  tc,(a0)         ;Save Translation Control Register
  331.     move.l  StackCopy,d1        ;Load it back from Ram
  332.  
  333.     btst.l  #31,d1          ;Test if MMU is already on
  334.     bne     mmu_on030       ;if so, bypass and return with TC contents 
  335.                         ;  as status
  336. SetMMU031:
  337.  
  338.     moveq   #0,d1           ;Clear out VBR, TC, and CACR
  339.     _MOVEC  d1,vbr
  340.  
  341. SetMMU032:
  342.  
  343.     lea.l   Zero,a0         ;Clear TC and cacr
  344.     _PMOVE  (a0),tc
  345.  
  346.     move.l  #$0808,d1
  347.     _MOVEC  d1,cacr         ;Turn off & dump Data and Instruction Caches
  348.        
  349.     lea.l   _CRP0,a0        ;Write MMU Root table pointer to SRP & URP
  350.     _PMOVE  (a0),crp
  351.  
  352.     lea.l   _TC030,a0       ;Load TC and activate the MMU
  353.     _PMOVE  (a0),tc
  354.  
  355.     move.l  #0,d1           ;Return code for testing if MMU was on at
  356.                         ;Start of SetMMU - 0 indicates it was off
  357. mmu_on030:
  358.     rts
  359.  
  360. ; Crude way of handling invalid and write access errors, 
  361. ;  all others will be sent to guru land via CBM's handler
  362.  
  363.  
  364.     CNOP    0,4         ;Align Stack
  365.  
  366. StackCopy:
  367.  
  368.     dc.l   0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  369.  
  370. _BusErrorHandler: 
  371.  
  372.     move.l  a5,SafeA5           ;Save on end of temporary stack
  373.     lea.l   _TempStack,a5       ;New Temporary storage area
  374.     movem.l d0-d2/a0-a2,-(a5)   ;Save minimal registers
  375.  
  376.     move.l  a7,a0               ;Copy the Stack Frame for Later Perusal
  377.     lea.l   StackCopy,a1
  378.     moveq   #14,d0             ;Do 15 times (does a copy on d0 = 0 count)
  379.  
  380. SCL:
  381.  
  382.     move.l  (a0)+,(a1)+
  383.     dbra    d0,SCL
  384.  
  385.     move.w  $c(a7),d0       ;Get Special Status Word
  386.     move.l  d0,d1           ;Save it for other tests
  387.     btst.l  #10,d0          ;Check for ATC fault
  388.     beq.w   BusError        ;Not an ATC fault - Probably a Bus Error
  389.     andi.l  #$18,d0         ;Check for TT=$0
  390.     bne.w   NotNormal       ;Not a Data Access Error
  391.     andi.l  #5,d1           ;Mask TM field from SSW
  392.     cmpi.l  #5,d1           ;Check TM=$5
  393.     beq.b   DoWB1           ;Supervisor, jump
  394.     cmpi.l  #1,d1           ;Check TM=$1 (User)
  395.     bne.w   NotNormal       ;Again, Not a data access error
  396.  
  397.                     ;We are an ATC Invalid access or 
  398.                     ; write fault error
  399. DoWB1:
  400.     move.l  $2C(a7),d2      ;Get WB1D
  401.     move.l  $28(a7),a2      ;Get WB1A
  402.     move.w  $12(a7),d0      ;Get WB1S
  403.     btst.l  #7,d0           ;Valid Write?
  404.     beq.b   DoWB2
  405.     bsr     WriteBack1      ;Perform WriteBack1
  406.  
  407. DoWB2:
  408.     move.l  $24(a7),d2      ;Get WB2D
  409.     move.l  $20(a7),a2      ;Get WB2A
  410.     move.w  $10(a7),d0      ;Get WB2S
  411.     btst.l  #7,d0           ;Valid Write?
  412.     beq.b   DoWB3
  413.     bsr     WriteBack       ;Perform WriteBack2
  414. DoWB3:  
  415.     move.l  $1c(a7),d2      ;Get WB3D
  416.     move.l  $18(a7),a2      ;Get WB3A
  417.     move.w  $e(a7),d0       ;Get WB3S
  418.     btst.l  #7,d0           ;Valid Write?
  419.     beq.b   Done
  420.     bsr     WriteBack       ;Perform WriteBack3
  421. Done:
  422.     movem.l (a5)+,d0-d2/a0-a2   ;Restore Registers
  423.     move.l  SafeA5,a5       
  424.     rte                     ;Return from exception
  425.  
  426. BusError:                   ;Routine to handle Bus Errors via Exceptions
  427.                             ;Under Construction
  428.     
  429. NotNormal:
  430.     movem.l (a5)+,d0-d2/a0-a2   ;Restore Registers
  431.     move.l  SafeA5,a5       
  432.     dc.w    $4ef9
  433. OH1:    dc.l    $0              ;jmp (OldHandler) - Address filled in
  434.                             ; by SetupBusErrorHandler()
  435.  
  436. WriteBack:                  ;At this point we only care about the 
  437.                             ;load Fault Address (jsr adds 4 to stack offset)
  438.     move.l  $18(a7),a1
  439.     cmpa.l  a2,a1           ;Compare against WBXA
  440.     beq.b   NotDo           ;Return if same-We don't want another fault!
  441.     andi.l  #$60,d0         ;Mask off Size + check for Longword
  442.     beq.b   LongWord        ;Yep, LongWord
  443.     cmpi.w  #$20,d0         ;Check for Byte access
  444.     beq.b   Byte            ;Yep, Byte
  445.     cmpi.w  #$40,d0         ;Check for Word Access
  446.     bne.b    Line           ;Nope, 16 Byte Line Access
  447. Word:
  448.     move.w  d2,(a2)         ;Perform Word Write
  449. NotDo:
  450.     rts
  451.  
  452. LongWord:
  453.  
  454.     move.l d2,(a2)          ;Perform Long word write
  455.     rts
  456.  
  457. Byte:   
  458.     move.b d2,(a2)          ;Perform Byte Write
  459.     rts
  460.  
  461.  
  462. Line:   
  463.     addq.l  #4,A7           ;I can't handle a line error here so I
  464.     bra NotNormal           ; punt and run CBM's handler (guruland) 
  465.  
  466. ;--------------------------------------------------------------------------------
  467. ;WriteBack1 handler for WB1X 68040 Access Error stack frame, Test code
  468. ;A0 unaltered
  469. ;WB1A in A2, WB1D in D2, WB1S in D0. D0,D1 & A1 are destroyed by the code  
  470. ;-------------------------------------------------------------------------------
  471.  
  472.  
  473. WriteBack1:         
  474.                             ;TT=0 Already tested for!
  475.     move.l  $18(a7),a1      ;Load Fault Address from Stack frame
  476.     cmpa.l  a2,a1           ;Compare against WB1A
  477.     beq.w   W1End           ;Return if same-We don't want another fault!
  478.     move.b  d0,d1           ;Copy WB1S for trashing
  479.     andi.b  #$18,d1         ;Mask off TT field of WB1S
  480.     beq.w   W1End           ;Jump if not Normal Access Type
  481.     move.l  a2,d1           ;Copy Dest Address
  482.     andi.l  #3,d1           ;Get last two address bits
  483.     move.l  d1,a1           ;Save for Later
  484.     andi.l  #$60,d0         ;Mask off Size + check for Longword
  485.     beq.w   W1LongWord      ;Yep, LongWord
  486.     cmpi.b  #$20,d0         ;Check for Byte access
  487.     beq.w   W1Byte          ;Yep, Byte
  488.     cmpi.b  #$40,d0         ;Check for Word Access
  489.     bne.w   W1Line          ;Nope, 16 Byte Line Access
  490.  
  491. W1Word:                     ;If not one of above, must be Word
  492.  
  493.     cmpa.l  #0,a1           ;Check if WB1A Address is xxxxxx00
  494.     bne.b   WA1
  495. WA0:
  496.     moveq   #16,d1          ;Shift data right to fit d15:d0
  497.     ror.l   d1,d2   
  498.     move.w  d2,(a2)         ;Write Word to Address
  499.     bra.b   W1End           ;Done
  500. WA1:
  501.     cmpa.l  #1,a1           ;Check if WB1A Address is xxxxxx01  
  502.     bne.b   WA2 
  503.     moveq   #8,d1           ;Shift data right  to fit D15:0
  504.     ror.l   d1,d2           ;  instead of D23:8
  505.     move.w  d2,(a2)         ;Write word to address
  506.     rts                     ;Done
  507. WA2:
  508.     cmpa.l  #2,a1           ;Check if WB1A address is xxxxxx10
  509.     bne.b   WA3         
  510.     move.w  d2,(a2)         ;Data register aligned OK, Write Word
  511.     rts                     ;Done
  512. WA3:
  513.     cmpa.l  #3,a1           ;Check if WB1A address is xxxxxx11
  514.     bne.b   W1End           ;Something wrong if not == 3!
  515.     moveq   #8,d1           ;Shift data from 7:0,31:24 to 15:0
  516.     rol.l   d1,d2   
  517.     move.w  d2,(a2)         ;Perform Byte Write
  518.  
  519. W1End:
  520.     rts
  521.  
  522. W1LongWord:
  523.  
  524.     cmpa.l  #0,a1           ;Check if WB1A is xxxxxx00
  525.     bne.b   LA1
  526. LA0:
  527.     move.l  d2,(a2)         ;Everything aligned, write long word
  528.     rts                     ;Done
  529. LA1:
  530.     cmpa.l  #1,a1           ;Check if WB1A is xxxxxx01
  531.     bne.b   LA2
  532.     moveq   #8,d1           ;Rotate left to align data from 23:0,31:24
  533.     ror.l   d1,d2           ;  to 31:0
  534.     move.l  d2,(a2)         ;Perform long word write
  535.     rts                     ;Done
  536. LA2:
  537.     cmpa.l  #2,a1           ;Check if WB1A is xxxxxx10
  538.     bne.b   LA3
  539.     moveq   #16,d1          ;Rotate from 15:0,31:16 to 31:0
  540.     ror.l   d1,d2   
  541.     move.l  d2,(a2)         ;Perform long word write
  542.     rts                     ;Done
  543. LA3:
  544.     cmpa.l  #3,a1           ;Check if WB1A is xxxxxx11
  545.     bne.b   LAEnd           ;Something wrong if not!
  546.     moveq   #8,d1           ;Rotate from 7:0,31:8 to 31:0
  547.     rol.l   d1,d2   
  548.     move.l  d2,(a2)         ;Perform long word write    
  549. LAEnd:
  550.     rts
  551.  
  552. W1Byte:         ;a0 contains WB1A, a1 is masked WB1A, d2 = WB1D 
  553.  
  554.     cmpa.l  #0,a1           ;Check if WB1A is xxxxxx00
  555.     bne.b   BA1
  556. BA0:
  557.     moveq   #8,d1           ;Rotate from 31:24 to 7:0
  558.     rol.l   d1,d2   
  559.     move.b  d2,(a2)         ;Perform Byte Write
  560.     rts                     ;Done
  561. BA1:
  562.     cmpa.l  #1,a1           ;Check if WB1A is xxxxxx01
  563.     bne.b   BA2
  564.     moveq   #16,d1          ;Rotate from 23:16 to 7:0           
  565.     ror.l   d1,d2   
  566.     move.b  d2,(a2)         ;Perform Byte Write
  567.     rts                     ;Done
  568. BA2:
  569.     cmpa.l  #2,a1           ;Check if WB1A is xxxxxx10
  570.     bne.b   BA3         
  571.     moveq   #8,d1           ;Rotate from 15:8 to 7:0
  572.     ror.l   d1,d2   
  573.     move.b  d2,(a2)         ;Perform Byte Write
  574.     rts
  575. BA3:
  576.     cmpa.l  #3,a1           ;Check if WB1A is xxxxxx11
  577.     bne.b   BAEnd   
  578.     move.b  d2,(a2)         ;Perform Byte Write - Alignment ok  
  579. BAEnd:
  580.     rts
  581.  
  582. W1Line:                 
  583.     addq.l  #4,a7           ;I can't handle a line error here, so I
  584.     bra NotNormal           ;punt and run CBM's handler (guruland)
  585.  
  586. ;
  587. ; SFColdReboot is required to ensure my MMU tables are loaded prior to reboot.
  588. ;
  589. SFColdReboot:
  590.  
  591.     movem.l d0-d7/a0-a6,-(a7)   ;Save Registers
  592.  
  593.     move.l ABSEXECBASE,a6       ;ensure ExecBase is in a6
  594.     movea.l a6,a1               ;Library for SetFunction to operate on
  595.     lea.l NewColdReboot,a0      ;Address of replacement routine in a0
  596.     move.l a0,d0                ;move address to d0
  597.     lea.l _LVOColdReboot,a0     ;Load library offset into a0
  598.     jsr _LVOSetFunction(a6)     ;Perform the Setfunction
  599.     move.l  d0,ROMColdReboot    ;Save Old Vector
  600.  
  601.     movem.l (a7)+,d0-d7/a0-a6   ;Restore registers
  602.     rts
  603.  
  604. ;NewColdReboot restores the MMU for the 030 or 040 as other people's MMU
  605. ;  tools may have taken over. For guranteed ROM replacement, this code
  606. ;  will jam the original SRP/URP for the 040 and CRP0 & CRP1 for the 030. 
  607.  
  608. NewColdReboot:
  609.     btst.b  #AFB_68040,ATNFLGS(a6)
  610.     beq.b   ResetTest030        ;Jump to next test if not 040
  611.     
  612.     lea.l    My040ResetCode,a5  ;Load code pointer 
  613.     jsr     _LVOSupervisor(a6)  ;Run code in Supervisor Mode
  614.     rts                     ;We won't return here
  615.  
  616. ResetTest030:
  617.     btst.b  #AFB_68030,ATNFLGS(a6)  ;Test for 030
  618.     bne.b   Reset030    
  619.  
  620.     btst.b  #AFB_68020,ATNFLGS(a6)  ;Test for 020 (851 assumed)
  621.     beq.b   NOMMUResetCode          ;Run RomColdReboot if not a 020 or better
  622.  
  623. Reset030:
  624.     lea.l    My030ResetCode,a5  ;Load code pointer 
  625.     jsr     _LVOSupervisor(a6)  ;Run code in Supervisor Mode
  626.     rts                     ;We will Never Return here
  627.  
  628. NOMMUResetCode:
  629.     lea.l   ROMColdReboot,a0    ;Load Old Reset Vector
  630.     jmp     (a0)                ;Reboot Machine
  631.                             ;Never get back here!
  632.     rts                     ;Not needed, but here for safety
  633.  
  634. My040ResetCode:
  635.     moveq   #0,d1               ;0 clears out TC etc in SetMMU2
  636.     jsr     SetMMU2             ;Turn on 040 MMU
  637.     bra     Reboot              ;Reboot
  638.  
  639.     rte             ;Will Never Return
  640.  
  641. My030ResetCode:
  642.  
  643.     jsr     SetMMU032           ;Turn on 030 MMU
  644.     bra     Reboot              ;Reboot
  645.                             ;Will Never Return
  646.     rte                     ;Not Needed, but just to be safe
  647.  
  648.     CNOP 0,4                ;LongWord align stack
  649.  
  650.                 DC.L 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
  651. _TempStack:     DC.L $0 
  652. SafeA5:         DC.L $0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 ; Buffer for overwrites
  653.  
  654. _EndTag:
  655.  
  656. ;--------------------End of Protected Romtag Space-------------------------------
  657. @CachesOff:
  658.  
  659.     movem.l d0-d7/a0-a6,-(sp)   ;Save Registers
  660.     move.l  ABSEXECBASE,a6      ;Load Execbase
  661.  
  662.     btst.b  #AFB_68040,ATNFLGS(a6)
  663.     beq.b   CS030            ;Don't mess with anything if not 040
  664.  
  665. CS040:
  666.     lea.l   CachesOff040,a5     ;Load code pointer 
  667.     jsr     _LVOSupervisor(a6)  ;Run code in Supervisor Mode
  668.     bra     COExit
  669.  
  670. CS030:
  671.     lea.l   CachesOff030,a5
  672.     jsr        _LVOSupervisor(a6)
  673.  
  674. COExit:
  675.     movem.l (a7)+,d0-d7/a0-a6   ;Restore Registers
  676.     rts                     ;Return to OS
  677.  
  678. CachesOff030:
  679.  
  680.      move.l  #$0808,d1
  681.      _MOVEC  d1,cacr         ;Turn off & dump Data and Instruction Caches
  682.      rte
  683.  
  684. CachesOff040:
  685.  
  686.      moveq   #0,d1
  687.      _MOVEC  d1,cacr
  688.     _CPUSHA040              ;Dump Caches
  689.     _PFLUSHA040             ;Clear out ATC
  690.     _CINVA040               ;Invalidate caches
  691.      rte
  692.  
  693. ;
  694. ; SF_Supervisor is required because when OVRMMU option is used, the previous
  695. ; ROM could be in RAM, and in particular, the new ROM will probably overwrite
  696. ; the contents of the old, invalidating all library LVOs. Thus, Supervisor
  697. ; must be setfunctioned to prevent MakeRomTag, JTROM, JTROM13030 et.al from
  698. ; going blooey only for the duration it takes to move the rom and reboot. 
  699. ; Supervisor is not Setfunctioned unless the rom is to be overwritten and a
  700. ; new OS loaded! 
  701. ;
  702. ; Note - the calling 'C' code must Disable() before calling this routine!
  703. ;
  704.  
  705. @SF_Supervisor:
  706.  
  707.     movem.l d0-d7/a0-a6,-(a7)    ;Save Registers
  708.     move.l ABSEXECBASE,a6        ;ensure ExecBase is in a6
  709.  
  710.                  ;By being in Supervisor mode before
  711.                  ;the SetFunction(), it prevents a privlege
  712.                  ;exception from occuring until I can mash
  713.                  ;down my vector immediately after SetFunction() 
  714.     jsr _LVOSuperState(a6)    
  715.  
  716.     movea.l a6,a1               ;Library for SetFunction to operate on
  717.     lea.l MySupervisor,a0       ;Address of replacement routine in a0
  718.     move.l a0,d0                ;move address to d0
  719.     lea.l _LVOSupervisor,a0     ;Load library offset into a0
  720.     jsr _LVOSetFunction(a6)     ;Perform the Setfunction
  721.  
  722.    lea.l MyExcepHndlr,a1    ;Address of Privlege violation handler
  723.     _MOVEC vbr,d0        ;Get vbr
  724.     move.l  d0,a0        ;Move to address register
  725.     move.l  a1,$20(a0)           ;Write to exception table
  726.     move.l  a1,$20                ;Write to address $20 for good measure 
  727.  
  728.     andi  #$fdff,sr        ;Go back to User mode
  729.     movem.l (a7)+,d0-d7/a0-a6
  730.     rts
  731.  
  732. MySupervisor:                     ;This routine is relocatable
  733.  
  734.     ORI.W    #$2000,SR       ;In user mode, creates exception #8 and
  735.                     ;control never returns to here
  736.                     ;If already in Supervisor mode, pass thru
  737.         SUBQ.L    #8,SP            ;Reduce the Stack pointer to create space for
  738.                                 ;a simulated exception frame $0, so the user's
  739.                                 ;RTE will run the desired instruction without
  740.                 ;messing up his stack!     
  741.     MOVE.W    SR,(SP)            ;Push the current SR onto the stack so after
  742.                     ;the user code's RTE, SR will be loaded from
  743.                 ;stack and we will still be in Supervisor mode.
  744.     MOVE.L  A0,SV1        ;Save A0
  745.     LEA.L    MyRTS,A0    ;Load address of RTS
  746.     MOVE.L    A0,2(SP)    ;Change the Return address, so an RTS will be
  747.                 ;run to exit the Supervisor() function
  748.     MOVEA.L    SV1,A0        ;Restore A0
  749.     MOVE.W    #$20,6(SP)      ;Write Privilege exception vector code (frame
  750.                 ;format $0) to complete exception fake
  751.     JMP    (A5)        ;Jump to User code
  752.  
  753. MyExcepHndlr:            ;The address of this routine must be written 
  754.                 ;to vbr+$20
  755.     MOVE.L    A0,SV1        ;SAVE A0 as we need it for address comparisons
  756.     LEA.L    MySupervisor,A0    ;Get Address of opcode which might have caused
  757.                 ;the exception
  758.      CMPA.L    2(SP),A0    ;Check address of the instruction which created
  759.                 ;the exception
  760.     BNE.W    Reboot        ;It wasn't from Supervisor(), so jump to Reboot
  761.     LEA.L    MyRTS,A0    ;Load Address of RTS into A0
  762.     MOVE.L    A0,2(SP)         ;Change value of return address on the stack
  763.                 ;so that Supervisor() will RTS immediately 
  764.                 ;after the RTE
  765.         MOVEA.L  SV1,A0        ;Restore A0
  766.     JMP    (A5)        ;Perform User's code, his RTE will return
  767.                 ;from the exception to the following RTS
  768. MyRTS:    RTS            ;Return from the Supervisor() function
  769. SV1:    DC.L     0
  770.  
  771. @JTRom:                     ;Jump To MMUed Rom 
  772.     move.l  ABSEXECBASE,a6      ;Load Execbase
  773.     lea.l   JTSRom,a5
  774.     jsr     _LVOSupervisor(a6)  ;In Supervisor state when you jump to ROM
  775.     rts                    ; Should never get here!!!
  776.  
  777. JTSRom:
  778.  
  779.     move.l  ABSEXECBASE,a6      ;Load Execbase
  780.     btst.b  #AFB_68040,ATNFLGS(a6)
  781.     beq.b   JTRom030            ;Don't mess with anything if not 040
  782.  
  783.     bsr     SetMMU1             ;Turn MMU on and set up default MMU state
  784.     bra     Reboot
  785.  
  786. JTRom030:                   ;Jump To MMUed Rom
  787.  
  788.     bsr     SetMMU031       ;Turn MMU on and set up default MMU state
  789.     bra     Reboot          ;jump to longword aligned routine
  790.  
  791. @MakeRomTag:
  792.  
  793.     movem.l d0-d7/a0-a6,-(a7)   ;Setup romtag in memory
  794.     move.l  ABSEXECBASE,a6      ;Get execbase
  795.     lea.l   KickMem+14,a0       ;Set up KickMemPtr
  796.     move.l  _NumMemAreas,d0     ;Variable length number of ram areas
  797.     move.l  d0,d1
  798.     addq.l  #1,d0               ;Add extra to romtag list
  799.     move.w  d0,(a0)+            ;  to KickMemList
  800.     lsl     #3,d1               ;8 bytes per memory entry
  801.     adda.l  d1,a0               ;Point to End of List
  802.     lea.l   _SaveMem,a1
  803.     move.l  a1,(a0)+            ;Add  Romtag Allocation Start
  804.     lea.l   _EndTag-_SaveMem,a1
  805.     move.l  a1,(a0)+            ;Add  Romtag Allocation Length
  806.  
  807.     lea.l   KickMem,a0
  808.     move.l  KickMemPtr(a6),(a0) ;old pointer in ln_Succ
  809.     move.l  a0,KickMemPtr(a6)
  810.  
  811. ;
  812. ; Set up KickTagPtr
  813. ;
  814.     lea     KickTag,a0
  815.  
  816.     move.l  KickTagPtr(a6),4(a0)    ;Old pointer at the end of the table
  817.     beq.s   .nomore
  818.  
  819.     bset.b  #7,4(a0)        ;Bit 31 = Extend table
  820.  
  821. .nomore:
  822.     move.l  a0,KickTagPtr(a6)
  823.  
  824. ;
  825. ; Calculate checksum
  826. ;
  827.  
  828.     jsr     _LVOSumKickData(a6)
  829.     move.l  d0,KickCheckSum(a6)
  830.     movem.l (a7)+,d0-d7/a0-a6
  831.     rts
  832.  
  833. @MyColdReboot:                  ;KILLROM function
  834.  
  835.     move.l  ABSEXECBASE,a6      ;Get Execbase
  836.     jsr     _LVODisable(a6)
  837.     jsr     _LVOSuperState(a6)  ;Goto Supervisor mode
  838.     moveq   #0,d0
  839.     move.l  d0,$7fc5000         ;Blow Away 1.3 Romtag
  840.     move.l  d0,$6a0
  841.     jsr     _IDCpu
  842.     btst.l  #AFB_68040,d0
  843.     beq.b   ColdReboot030       ;Don't mess with anything if not 040
  844.  
  845.     bsr     SetMMU              ;Setup MMU to default
  846.  
  847.     moveq   #0,d0               ;Turn off MMU (SetMMU turned it on)
  848.     _MOVEC  d0,tc
  849.  
  850.     _CPUSHA040
  851.     _PFLUSHA040
  852.     _CINVA040
  853.    
  854.     bra.b   CommonReboot
  855.  
  856. ColdReboot030:
  857.                 
  858.     bsr     SetMMU030       ;Setup MMU to default
  859.     lea.l   Zero,a0
  860.     _PMOVE  (a0),tc
  861.  
  862. CommonReboot:
  863.     moveq   #0,d0
  864.     _MOVEC  d0,cacr
  865.     moveq   #$52,d1         ;Number of longwords to kill
  866.     move.l  d0,(a6)         ;blow away exec!
  867. tloop:  
  868.     move.l  d0,(a6)+        ;kill area above execbase
  869.     dbra    d1,tloop
  870.  
  871.     moveq   #0,d0       
  872.     moveq   #$52,d1
  873. tloop1: 
  874.     move.l  d0,-(a6)        ;Kill area below execbase
  875.     dbra    d1,tloop1
  876.                 
  877.     clr.l   ColdCapture(a6) 
  878.     clr.l   CoolCapture(a6)
  879.     clr.l   WarmCapture(a6)     ;Clear vectors and reboot
  880.     clr.l   KickTagPtr(a6)
  881.     clr.l   KickMemPtr(a6)
  882.     bra     Reboot
  883.  
  884. @KillRomTags:
  885.  
  886.     move.l  d0,-(a7)            ;Push d0
  887.     move.l  #0,d0               ;Load Zero
  888.     move.l  d0,initDDescrip     ;Kill Romtag header 2.0+
  889.     move.l  d0,initDDescrip2    ;Kill Romtag header 1.3
  890.     move.l  (a7)+,d0            ;Pop d0
  891.     rts                     ;Return
  892.  
  893. ;--------------------------------------------------------------------------------
  894. ; Note: FastRom is not recoverable due to when program exits, romtag and Bus Error
  895. ; Handler are susceptible to getting overwritten. So it was chosen not to load
  896. ; the romtag into exec, and to have the setup die on reset. Because of this the
  897. ; NoCatchRom option is ignored when entered with the Fastrom parameter. Bus
  898. ; error generation (NOBUSERRORS option) is settable in Fastrom.
  899. ;---------------------------------------------------------------------------------  
  900.  
  901. @SpeedRom: 
  902.  
  903.     movem.l d0-d7/a0-a6,-(a7)   ;Save Registers
  904.     move.l  ABSEXECBASE,a6      ;Load Execbase
  905.     cmpi.w  #36,LIB_VERSION(a6)
  906.     blt.b   SRExit              ;1.3 we are already in MMU!
  907.     btst.b  #AFB_68040,ATNFLGS(a6)
  908.     beq.b   _SpeedRom030        ;Don't mess with anything if not 040
  909.  
  910.     lea.l   SpeedCode,a5        ;Load code pointer 
  911.     jsr     _LVOSupervisor(a6)  ;Run code in Supervisor Mode
  912. SRExit:
  913.     movem.l (a7)+,d0-d7/a0-a6   ;Restore Registers
  914.     rts                     ;Return to OS
  915.  
  916. SpeedCode:
  917.         
  918.     move.l  _BusErr,d0          ;Check if we want to disable Bus Errors
  919.     cmpi.l  #0,d0           
  920.     beq.b   DoneBus2            ;Branch if non zero
  921.     move.b  #0,($DE0000)        ;Set Buster to no Bus Error time out
  922.  
  923. DoneBus2:
  924.  
  925.     moveq   #0,d1               ;Bypass clearing VBR in SetMMU
  926.     bsr     SetMMU2             ;Set up MMU
  927.  
  928.     _CPUSHA040  ;MMU will be on at this time, this code is sensitive
  929.     _PFLUSHA040 ; to what the previous mttx registers were. In particular,
  930.     _CINVA040   ; The area representing the area that this code resides
  931.                 ; in must be adjusted such that it doesn't go 'away'.
  932.  
  933.     move.l  _Z3cache,d1     ;if d1 is non-zero, turn on dttx copyback mode
  934.     cmpi.l  #0,d1
  935.     beq     BypassMMU2         ; Zero, therefore leave dttx as is  
  936.  
  937.     move.l  #$08f7c020,d0       ;Setup Ram for Copyback cacheable
  938.     _MOVEC  d0,dtt1         ; Had to be previously noncacheable, nonserialized
  939.     move.l  #$04fbc020,d0       ; for OS memory determination.
  940.     _MOVEC  d0,dtt0     
  941.  
  942.     _CPUSHA040
  943.     _PFLUSHA040 ;Flush ATC to make sure changes don't mess up anything
  944.     _CINVA040   ;Dump D & I caches for good measure
  945.  
  946. BypassMMU2:
  947.     move.l  #$80008000,d1
  948.     _MOVEC  d1,cacr             ;Turn on Data and Instruction Caches
  949.     rte
  950.  
  951. _SpeedRom030:
  952.  
  953.     lea.l   SpeedCode030,a5     ;Load code pointer 
  954.     jsr     _LVOSupervisor(a6)  ;Run code in Supervisor Mode
  955.     movem.l (a7)+,d0-d7/a0-a6   ;Restore Registers
  956.     rts                     ;Return to OS
  957.  
  958. SpeedCode030:
  959.  
  960.     bsr     SetMMU032           ;Set up MMU
  961.     move.l  #$2111,d1
  962.     _MOVEC  d1,cacr             ;Turn on Data and Instruction Caches
  963.     rte
  964.  
  965. @ForceTTX:                  ;Turn on nttx registers
  966.  
  967.     movem.l d0-d1/a5-a6,-(a7)   ;Save d0 & d1 & a5 - a6
  968.     move.l  ABSEXECBASE,a6      ;Get Execbase
  969.     
  970.     lea.l    ResetTTX,a5        ;Load code pointer 
  971.     jsr     _LVOSupervisor(a6)  ;Run code in Supervisor Mode
  972.  
  973.     movem.l (a7)+,d0-d1/a5-a6   ;Restore d0 & d1
  974.     rts
  975.  
  976. ResetTTX:
  977.  
  978.     _MOVEC  tc,d0           ;Save tc
  979.  
  980.     move.l  #0,d1
  981.     _MOVEC  d1,tc           ;Turn tc off
  982.  
  983.     _CPUSHA040              ;Dump and Kill caches 
  984.     _PFLUSHA040
  985.     _CINVA040
  986.  
  987.     move.l  _Z3cache,d1     ;if d1 is non-zero, turn on dttx copyback mode
  988.     cmpi.l  #0,d1
  989.     beq     BypassMMU3      ;Zero, therefore leave dttx as is  
  990.  
  991.     move.l  #$04fbc020,d1       ;Set up MMU for default memory translation setup
  992.     _MOVEC  d1,dtt0
  993.     move.l  #$08f7c020,d1
  994.     _MOVEC  d1,dtt1
  995.     bra     DoIttx
  996.  
  997. BypassMMU3:
  998.  
  999.     move.l  #$04fbc040,d1       ;Set up MMU for default memory translation setup
  1000.     _MOVEC  d1,dtt0
  1001.     move.l  #$08f7c040,d1
  1002.     _MOVEC  d1,dtt1
  1003.  
  1004. DoIttx:
  1005.     move.l  #$04fbc000,d1
  1006.     _MOVEC  d1,itt0
  1007.     move.l  #$08f7c000,d1
  1008.     _MOVEC  d1,itt1
  1009.  
  1010.     _CPUSHA040              ;Dump and Kill caches once again
  1011.     _PFLUSHA040
  1012.     _CINVA040
  1013.  
  1014.     _MOVEC  d0,tc           ;Turn tc back on
  1015.  
  1016.     rte
  1017.  
  1018. @GetTC040:
  1019.  
  1020.     movem.l d1-d7/a0-a6,-(a7)
  1021.     move.l  ABSEXECBASE,a6      ; Get ExecBase
  1022.     lea     5$,a5               ; Get the start of the supervisor code
  1023.     jsr     _LVOSupervisor(a6)
  1024.     movem.l (a7)+,d1-d7/a0-a6
  1025.     rts
  1026. 5$
  1027.     _MOVEC  tc,d0
  1028.     rte
  1029.  
  1030. @GetTC030:
  1031.     movem.l d1-d7/a0-a6,-(a7)
  1032.     move.l  ABSEXECBASE,a6      ; Get ExecBase
  1033.     subq.l  #4,sp               ; Make a place to dump TC
  1034.     move.l  sp,a0
  1035.     lea     2$,a5               ; Get the start of the supervisor code
  1036.     jsr     _LVOSupervisor(A6)
  1037.     move.l  (sp),d0             ; Here's the result
  1038.     addq.l  #4,sp
  1039.     movem.l (a7)+,d1-d7/a0-a6
  1040.     rts
  1041. 2$
  1042.     _PMOVE  tc,(a0)
  1043.     rte
  1044.  
  1045. @GetCPUType:
  1046.     movem.l a4-a6,-(sp)         ; Save this register
  1047.     move.l  ABSEXECBASE,a6      ; Get ExecBase
  1048.     btst.b  #AFB_68040,ATNFLGS(a6)  ; Does the OS think an '040 is here?
  1049.     beq     0$
  1050.     move.l  #68040,d0           ; Sure does...
  1051.     movem.l (sp)+,a4-a6
  1052.     rts
  1053.  
  1054. 0$  btst.b  #AFB_68030,ATNFLGS(a6)  ; Does the OS think an '030 is here?
  1055.     beq     10$
  1056.     move.l  #68030,d0           ; Sure does...
  1057.     movem.l (sp)+,a4-a6
  1058.     rts
  1059.  
  1060. 10$ btst.b  #AFB_68020,ATNFLGS(a6)  ; Does the OS think an '020 is here?
  1061.     beq     20$
  1062.     move.l  #68020,d0       ; Sure does...
  1063.     movem.l (sp)+,a4-a6
  1064.     rts
  1065.  
  1066. 20$ moveq   #0,d0           ; Not an '040
  1067.     movem.l (sp)+,a4-a6
  1068.     rts
  1069.  
  1070. @JTRom13030:     
  1071.     jmp     $7fc000c        ;init routine in 1.3 Bonus
  1072.  
  1073.     CNOP 0,4
  1074. ;-----------------------------------------------------------------------
  1075. ; From here on is protected from erasure during reboot
  1076. ;-----------------------------------------------------------------------
  1077. ;-----------------------------------------------------------------------
  1078. ; A romtag structure.  Both "exec" and "ramlib" look for
  1079. ; this structure to discover magic constants about you
  1080. ; (such as where to start running you from...).
  1081. ;-----------------------------------------------------------------------
  1082.  
  1083.    ; Most people will not need a priority and should leave it at zero.
  1084.    ; the RT_PRI field is used for _configuring the roms.  Use "mods" from
  1085.    ; wack to look at the other romtags in the system
  1086.  
  1087. initDDescrip2:
  1088.                         ; STRUCTURE RT,0
  1089.      DC.W    RTC_MATCHWORD      ; UWORD RT_MATCHWORD
  1090.      DC.L    initDDescrip2      ; APTR  RT_MATCHTAG
  1091.      DC.L    _EndTag2           ; APTR  RT_ENDSKIP
  1092.      DC.B    RTF_COLDSTART      ; UBYTE RT_FLAGS
  1093.      DC.B    VERSION            ; UBYTE RT_VERSION
  1094.      DC.B    NT_UNKNOWN         ; UBYTE RT_TYPE
  1095.      DC.B    MYPRI              ; BYTE  RT_PRI
  1096.      DC.L    modName2           ; APTR  RT_NAME
  1097.      DC.L    idString2          ; APTR  RT_IDSTRING
  1098.      DC.L    _InitRoutine2      ; APTR  RT_INIT
  1099.  
  1100.     CNOP 0,4
  1101.  
  1102. ;
  1103. ; It is assumed that _InitRoutine will only be run under 1.3 as
  1104. ; it is mapped into f05xxx by the 1.3 MMU routine. Since 2.0
  1105. ; requires a kicktag pointer for non-fxxxxx romtags, it should
  1106. ; not be found and executed under 2.0. Under 1.3, it will install
  1107. ; the ColdInit routine as the ColdCapture vector. Should the 
  1108. ; System be hardware rebooted via keyboard, the 2.0 rom will take
  1109. ; over, but will use the pre-existing 1.3 execbase for Coldcapture
  1110. ; if it passes the checksum consistancy checks. The ColdCapture
  1111. ; routine then IDs the OS version. If 1.3, then it returns, if 
  1112. ; 2.0, it then jumps to one of the two CPU routines which reenable the
  1113. ; MMU and restart 1.3. The near impossible is achievable!
  1114. ;
  1115. ; Note that I blast over the ColdCapture vector rather than chaining
  1116. ; as I am at such a high priority in the boot sequence that no one is
  1117. ; supposed to be able to get to ColdCapture ahead of me. Now if 
  1118. ; another program blows away Coldcapture, then reboot will not survive
  1119. ; a hardware reset.
  1120. ;
  1121.  
  1122. _InitRoutine2:  
  1123.     
  1124.     movem.l d0-d7/a0-a6,-(a7)   ;Save Registers
  1125.     move.l  ABSEXECBASE,a6      ;Get Execbase
  1126.  
  1127.     lea.l   ColdInit,a0         ;Romtag ColdCapture address
  1128.     lea.l   initDDescrip2,a1    ;Romtag Start Address
  1129.     suba.l  a1,a0               ;length to ColdInit
  1130.     move.l  #$7fc5000,a1        ;Final Start Address of Romtag
  1131.     add.l   a1,a0               ;Add Offset to get Final ColdInit address
  1132.     move.l  a0,ColdCapture(a6)  ;Move to ColdCapture
  1133.  
  1134. ; Recalculate checksum
  1135.  
  1136.     lea    $22(a6),a0
  1137.     moveq  #$16,d0
  1138.     moveq  #0,d1
  1139.  
  1140. sumloop2:
  1141.  
  1142.     add.w  (a0)+,d1
  1143.     dbra   d0,sumloop2
  1144.     not.w  d1
  1145.     move.w d1,$52(a6)
  1146.  
  1147. InitExit2:
  1148.  
  1149.     movem.l (a7)+,d0-d7/a0-a6   ;Restore Registers
  1150.     rts
  1151.  
  1152. ColdInit:               ;Remember, we are in Supervisor Mode
  1153.                         ;during ColdCapture
  1154.  
  1155.     movem.l d0-d1/a0,-(a7)      ;Save Registers
  1156.     cmpi.w  #$1114,($f80000)    ;Test if 2.0
  1157.     bne     ExitCold
  1158.  
  1159.     bsr     _IDCpu              ;CPU Type returned in d0
  1160.  
  1161.     btst.l  #AFB_68040,d0
  1162.     beq.b   Do0302              ;Jump to next test if not 040
  1163.  
  1164.     bra.b   My040InitCode2      ;Load code pointer 
  1165.     
  1166.  
  1167. Do0302:
  1168.     btst.l  #AFB_68030,d0       ;Test for 030
  1169.     beq.b   ExitCold            ;Just return if not a 020 or better
  1170.  
  1171. Ok0302:
  1172.  
  1173.     lea.l   TC0302(pc),a0
  1174.     _PMOVE  (a0),tc
  1175.  
  1176.  
  1177.     CNOP 0,4
  1178.  
  1179. RB030:
  1180.     reset
  1181.     jmp    $fc0002            ;Load code pointer 
  1182.  
  1183. TC0302:    DC.L $80f08630
  1184.  
  1185. ExitCold:
  1186.  
  1187.     movem.l (a7)+,d0-d1/a0      ;Restore Registers
  1188.     jmp     (a5)                ;Return to OS
  1189.  
  1190. My040InitCode2:
  1191.  
  1192.     moveq   #0,d1           ;Clear out VBR, TC, and CACR
  1193.     _MOVEC  d1,vbr
  1194.  
  1195.     _MOVEC  d1,tc
  1196.     _MOVEC  d1,cacr
  1197.  
  1198.     _CPUSHA040              ;Dump Caches
  1199.     _PFLUSHA040             ;Clear out ATC
  1200.     _CINVA040               ;Invalidate caches
  1201.  
  1202.     move.l  #$04fbc040,d1       ;Set up MMU for default memory translation setup
  1203.     _MOVEC  d1,dtt0
  1204.     move.l  #$08f7c040,d1
  1205.     _MOVEC  d1,dtt1
  1206.  
  1207.     move.l  #$04fbc000,d1
  1208.     _MOVEC  d1,itt0
  1209.     move.l  #$08f7c000,d1
  1210.     _MOVEC  d1,itt1
  1211.  
  1212.     move.l  #$7fc6000,d1        ;Write MMU Root table pointer to SRP & URP
  1213.     _MOVEC  d1,srp
  1214.     _MOVEC  d1,urp
  1215.  
  1216.     _CPUSHA040              ;Dump and Kill caches once again
  1217.     _PFLUSHA040
  1218.     _CINVA040
  1219.  
  1220.     move.w  #$C000,d0       ;Load TC and activate the MMU
  1221.     _MOVEC  d0,tc
  1222.  
  1223.     bra     RB030
  1224.  
  1225. _IDCpu:
  1226.     _MOVEC    cacr,d1           ; Get the Cache Control Register
  1227.     move.l   #$8000,d0          ; Make a copy
  1228.     _MOVEC   d0,cacr            ; Try to set the CACR
  1229.     _MOVEC   cacr,d0            ; Save the real value
  1230.     _MOVEC   d1,cacr            ; Restore it
  1231.     cmpi.l   #$8000,d0          ; Check for 040 bit
  1232.     beq      Load040            ; Yup, an 040
  1233.     moveq    #0,d0  
  1234.     bset.l   #AFB_68030,d0      ; Must be 020 or 030 
  1235.     rts
  1236.  
  1237. Load040:
  1238.     moveq   #0,d0
  1239.     bset.l  #AFB_68040,d0       
  1240.     rts
  1241.  
  1242.    ; this is the name that the module will have
  1243.  
  1244. modName2:   DC.B   'ReBoot13.romtag  ',0
  1245.  
  1246. idString2:  DC.B   'ReBoot13.romtag 3.31 (10/25/92)',13,10,0
  1247.  
  1248. _EndTag2:
  1249.  
  1250.  
  1251. ;--------------------End of Protected Romtag Space-------------------------------
  1252.  
  1253. ;
  1254. ; Move Romtag to $7fc5000 which appears at f05000 via MMU tables
  1255. ;
  1256.  
  1257. @MakeRomTag13:
  1258.         movem.l d0-d1/a0-a3,-(a7)      ;Save Registers
  1259.  
  1260.         lea.l   _EndTag2,a0      ;Romtag End address
  1261.         lea.l   initDDescrip2,a1 ;Romtag Start Address
  1262.         suba.l  a1,a0            ;Romtag length
  1263.         move.l  a0,a3
  1264.         move.l  #$f05000,a2      ;Remapped romtag Start Address
  1265.         add.l   a2,a3            ;Relocated _EndTag2 Address
  1266.                 move.l  a0,d0    ;Number of Bytes to copy
  1267.         move.l  #$7fc5000,a0     ;Final Address of Romtag
  1268. MRTLoop:    
  1269.         move.b     (a1)+,(a0)+      ;Copy romtag to new location
  1270.         dbra    d0,MRTLoop
  1271.  
  1272. ;
  1273. ;Patch relocated Romtag
  1274. ;
  1275.         move.l  a2,($7fc5002)       ;New initDDescript2
  1276.         move.l  a3,($7fc5006)       ;EndTag2
  1277.  
  1278.         lea.l   modName2,a1         ;Calc New modname after reloc
  1279.         lea.l   initDDescrip2,a3    ;Start of Existing romtag
  1280.         sub.l   a3,a1
  1281.         add.l   a2,a1
  1282.         move.l  a1,($7fc500e)       ;Store in RT_NAME
  1283.  
  1284.         lea.l   idString2,a1        ;Calculate loc of new idString2
  1285.         sub.l   a3,a1
  1286.         add.l   a2,a1
  1287.         move.l  a1,($7fc5012)       ;Store in RT_IDSTRING
  1288.  
  1289.         lea.l   _InitRoutine2,a1    ;Calc relocated InitRoutine2
  1290.         sub.l   a3,a1
  1291.         add.l   a2,a1
  1292.         move.l  a1,($7fc5016)       ;Store in RT_INIT
  1293.  
  1294.         movem.l (a7)+,d0-d1/a0-a3   ;Restore Registers
  1295.         rts
  1296.  
  1297.         end
  1298.